﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace Mozlite.Cryptography
{
    /// <summary>
    /// 对称加密算法的加密类。
    /// </summary>
    public class Encryptor
    {
        /// <summary>
        /// 初始化类<see cref="T:Encryptor"/>。
        /// </summary>
        /// <param name="algorithm">加密算法类型<see cref="T:Mozlite.Cryptography.EncryptionAlgorithm"/>。</param>
        public Encryptor(EncryptionAlgorithm algorithm)
        {
            transformer = new EncryptTransformer(algorithm);
        }

        private EncryptTransformer transformer;
        private byte[] iv;
        private byte[] key;
        /// <summary>
        /// 加密数据。
        /// </summary>
        /// <param name="data">需要加密的数据。</param>
        /// <param name="key">加密钥匙。</param>
        /// <returns>返回加密后的数据。</returns>
        public byte[] Encrypt(byte[] data, byte[] key)
        {
            //设置将保存加密数据的流。
            MemoryStream ms = new MemoryStream();
            transformer.IV = iv;
            ICryptoTransform transform = transformer.GetCryptoServiceProvider(key);
            CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
            try
            {
                //加密数据，并将它们写入内存流。
                cs.Write(data, 0, data.Length);
            }
            catch (Exception ex)
            {
                throw new Exception("将加密数据写入流时 出错： \n" + ex.Message);
            }
            //为客户端进行检索设置初始化向量和密钥
            this.key = transformer.Key;
            iv = transformer.IV;
            cs.FlushFinalBlock();
            cs.Close();
            //发送回数据。
            return ms.ToArray();
        }
        /// <summary>
        /// 获取或设置初始化向量。
        /// </summary>
        public byte[] IV
        {
            get { return iv; }
            set { iv = value; }
        }
        /// <summary>
        /// 获取密钥。
        /// </summary>
        public byte[] Key
        {
            get { return key; }
        }
        /// <summary>
        /// 生成密钥。
        /// </summary>
        /// <param name="algorithm">加密方法枚举类。</param>
        /// <returns>如果是双向加密方法，则返回相应的密钥，否则返回<c>null</c>。</returns>
        public static byte[] GenerateKey(EncryptionAlgorithm algorithm)
        {
            // 选取提供程序。
            switch (algorithm)
            {
                case EncryptionAlgorithm.Des:
                    {
                        DES des = new DESCryptoServiceProvider();
                        des.Mode = CipherMode.CBC;
                        return des.Key;
                    }
                case EncryptionAlgorithm.TripleDes:
                    {
                        TripleDES des3 = new TripleDESCryptoServiceProvider();
                        des3.Mode = CipherMode.CBC;
                        return des3.Key;
                    }
                case EncryptionAlgorithm.Rc2:
                    {
                        RC2 rc2 = new RC2CryptoServiceProvider();
                        rc2.Mode = CipherMode.CBC;
                        return rc2.Key;
                    }
                case EncryptionAlgorithm.Rijndael:
                    {
                        Rijndael rijndael = new RijndaelManaged();
                        rijndael.Mode = CipherMode.CBC;
                        return rijndael.Key;
                    }
                default:
                    {
                        return null;
                    }
            }
        }
    }
}
